import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from IPython.display import HTML
%matplotlib inline
Linear elasticity
Wrap-up: notebook
1D wave equation
\[\frac{\partial^2}{\partial t^2} \mathbf w = c \, \frac{\partial^2}{\partial x^2} \mathbf w\]
- Numerical solver based on finite differencing strategy:
def solve_wave_equation(c, L, T, dx, dt, initial_condition):
# check stability
if c * dt / dx > 1:
raise ValueError("Stability condition violated: c*dt/dx should be <= 1")
# discretize space-time domain
= np.arange(0, L + dx, dx)
x = np.arange(0, T + dt, dt)
t = np.zeros((len(t), len(x)))
u
# set initial condition
0, :] = initial_condition(x)
u[if len(t) > 1:
1, :] = u[0, :]
u[
# buffer coefficient
= (c * dt / dx)**2
C2
# time update
for n in range(1, len(t) - 1):
for i in range(1, len(x) - 1):
+ 1, i] = (2 * u[n, i] - u[n - 1, i] + C2 * (u[n, i + 1] - 2 * u[n, i] + u[n, i - 1]))
u[n
# set boundary condition
0] = 0
u[:, -1] = 0
u[:,
return x, t, u
- Set up simulation scenario
# Initial condition: Gaussian bump
def initial_gaussian_pulse(x, sigma=0.1, mu=0.5):
return np.exp(-((x - mu) / sigma)**2)
# Scenario parameters
= 0.25 # IC dev
sigma = 0.5 # IC center
mu = 1.0 # Wave speed
c = 2.0 # Total time
T = 1.0 # Domain size
L = 0.01
dx = 0.005 dt
- Deploy scenario 1 and 2
# Run simulation
= solve_wave_equation(c, L, T, dx, dt, lambda x: initial_gaussian_pulse(x, sigma, mu))
x, t, u
# Visualize result
= (10,8))
plt.figure(figsize =(0, L, 0, T), aspect='auto', origin='lower')
plt.imshow(u, extent='Wave amplitude')
plt.colorbar(label'Time')
plt.ylabel('Position')
plt.xlabel('Wave Propagation')
plt.title( plt.show()
# Run simulation
= 0.5
c = solve_wave_equation(c, L, T, dx, dt, lambda x: initial_gaussian_pulse(x, sigma, mu))
x, t, u
# Visualize result
= (10,8))
plt.figure(figsize =(0, L, 0, T), aspect='auto', origin='lower')
plt.imshow(u, extent='Wave amplitude')
plt.colorbar(label'Time')
plt.ylabel('Position')
plt.xlabel('Wave Propagation')
plt.title( plt.show()
- Animate result
%%capture
# Run simulation
= 1.0
c = solve_wave_equation(c, L, T, dx, dt, lambda x: initial_gaussian_pulse(x, sigma, mu))
x, t, u
def animate_wave(x, u, interval=50):
= plt.subplots()
fig, ax = ax.plot(x, u[0, :], 'k-')
line, min(), x.max())
ax.set_xlim(x.-1.1, 1.1)
ax.set_ylim('Position')
ax.set_xlabel('Wave amplitude')
ax.set_ylabel('1D Wave Propagation')
ax.set_title(
def update(frame):
line.set_ydata(u[frame, :])return line,
= FuncAnimation(fig, update, frames=len(u), interval=interval, blit=True)
ani #plt.close(fig)
return ani
= animate_wave(x, u) ani
HTML(ani.to_html5_video())# ani.save('./WavePropagation.mp4', writer='ffmpeg', dpi=300)
# Run simulation
= 1.0
c1 = 0.5
c2 = solve_wave_equation(c1, L, T, dx, dt, lambda x: initial_gaussian_pulse(x, sigma, mu))
x, t, u1 = solve_wave_equation(c2, L, T, dx, dt, lambda x: initial_gaussian_pulse(x, sigma, mu))
x, t, u2
# Visualize result
= (10,8))
plt.figure(figsize # fig, ax = plt.subplots(figsize=(10,8))
+u2, extent=(0, L, 0, T), aspect='auto', origin='lower')
plt.imshow(u1='Wave amplitude')
plt.colorbar(label'Time')
plt.ylabel('Position')
plt.xlabel('Wave Propagation')
plt.title( plt.show()
%%capture
= 0.5*(u1 + u2)
u_superposed
def animate_wave(x, u, interval=50):
= plt.subplots()
fig, ax = ax.plot(x, u[0, :], 'b-')
line, min(), x.max())
ax.set_xlim(x.-1.1, 1.1)
ax.set_ylim('Position')
ax.set_xlabel('Wave amplitude')
ax.set_ylabel('1D Wave Propagation')
ax.set_title(
def update(frame):
line.set_ydata(u[frame, :])return line,
= FuncAnimation(fig, update, frames=len(u), interval=interval, blit=True)
ani #plt.close(fig)
return ani
= animate_wave(x, u_superposed) ani
HTML(ani.to_html5_video())# ani.save('./WavePropagationSuperposed.mp4', writer='ffmpeg', dpi=300)
%%capture
def animate_wave(x, u, u_superposed, interval=50):
= plt.subplots()
fig, ax = ax.plot(x, u[0, :], 'k-', label='single wave')
line, = ax.plot(x, u_superposed[0, :], 'b-', label='superposed wave')
line2, min(), x.max())
ax.set_xlim(x.-1.1, 1.1)
ax.set_ylim('Position')
ax.set_xlabel('Wave amplitude')
ax.set_ylabel('1D Wave Propagation')
ax.set_title(
plt.legend()
def update(frame):
line.set_ydata(u[frame, :])
line2.set_ydata(u_superposed[frame, :])return line, line2
= FuncAnimation(fig, update, frames=len(u), interval=interval, blit=True)
ani #plt.close(fig)
return ani
= animate_wave(x, u, u_superposed) ani
HTML(ani.to_html5_video())# ani.save('./WavePropagationBoth.mp4', writer='ffmpeg', dpi=300)